home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
DJGPP
/
DJSRC111.ZIP
/
utils
/
oread.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-12
|
3KB
|
154 lines
#include <alloc.h>
#include <dos.h>
#include <stdio.h>
#include <bios.h>
#include <fcntl.h>
#define D_READ 2
#define D_WRITE 3
#define CACHE_SECTORS 18
typedef struct {
int fd; /* or drive, if cm set */
int cm, hm, sm;
long file_ptr;
void *cache;
long cache_fptr;
long cache_fptre;
int volume_in_drive;
} oread;
void *oread_open(char *fn)
{
oread *or;
if ((strlen(fn) == 2) && (fn[1] == ':'))
{
struct REGPACK r;
char buf[512];
int status;
switch (fn[0])
{
case 'a':
case 'A':
or = (oread *)malloc(sizeof(oread));
or->fd = 0;
break;
case 'b':
case 'B':
or = (oread *)malloc(sizeof(oread));
or->fd = 1;
break;
default:
printf("Invalid drive specified: %s\n", fn);
return 0;
}
while ((status = biosdisk(D_READ, or->fd, 0, 0, 1, 1, buf)) == 6)
/* wait for valid read */ ;
if (status)
return 0;
r.r_ax = 0x0800;
r.r_dx = or->fd;
intr(0x13, &r);
or->cm = (((r.r_cx & 0x00c0) << 2) | ((r.r_cx >> 8) & 0xff))+1;
or->hm = (r.r_dx >> 8)+1;
or->sm = r.r_cx & 0x3f;
or->file_ptr = 0L;
or->cache = (void *)malloc(512*CACHE_SECTORS);
or->cache_fptr = -512*CACHE_SECTORS;
or->cache_fptre = -512*CACHE_SECTORS;
or->volume_in_drive = 0;
return or;
}
else
{
int fd;
fd = _open(fn, O_RDONLY);
if (fd < 0)
return 0;
or = (oread *)malloc(sizeof(oread));
or->fd = fd;
or->cm = 0;
return or;
}
}
void oread_read(void *rv, void *buffer)
{
oread *r = (oread *)rv;
if (r->cm)
{
int c, h, s, v, sc;
if ((r->file_ptr >= r->cache_fptr) && (r->file_ptr < r->cache_fptre))
{
memcpy(buffer, (char *)(r->cache) + r->file_ptr - r->cache_fptr, 512);
r->file_ptr += 512;
return;
}
s = (unsigned long)(r->file_ptr) / 512;
h = s / r->sm;
c = h / r->hm;
v = c / r->cm;
s = s % r->sm;
h = h % r->hm;
c = c % r->cm;
if (v != r->volume_in_drive)
{
printf("Please insert volume %03d . . .", v);
fflush(stdout);
if (getch() == 3)
{
printf("^C\n");
exit(3);
}
printf("\n");
r->volume_in_drive = v;
r->cache_fptr = -512*CACHE_SECTORS;
}
sc = r->sm - s;
if (sc > CACHE_SECTORS)
sc = CACHE_SECTORS;
printf("v=%02d c=%02d h=%02d s=%02d n=%02d\r", v, c, h, s, sc);
fflush(stdout);
if (biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache))
biosdisk(D_READ, r->fd, h, c, s+1, sc, r->cache);
memcpy(buffer, r->cache, 512);
r->cache_fptr = r->file_ptr;
r->cache_fptre = r->cache_fptr + 512*sc;
r->file_ptr += 512;
}
else
{
if (_read(r->fd, buffer, 512) != 512)
{
printf("Unexpected end-of-file\n");
exit(1);
}
}
}
void oread_skip(void *rv, long skip_bytes)
{
oread *r = (oread *)rv;
if (r->cm)
{
r->file_ptr += skip_bytes;
}
else
{
lseek(r->fd, skip_bytes, 1);
}
}
void oread_close(void *rv)
{
oread *r = (oread *)rv;
if (r->cm == 0)
_close(r->fd);
else
free(r->cache);
free(r);
}